<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2019-2020 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: MUKE <513038996@qq.com>
// +----------------------------------------------------------------------
declare (strict_types = 1);
/**
 * 插件列表
 * @param $status int 0关闭的插件，1开启的插件 2所有插件
 */
function plugin_list($status = 1): array
{
    $list   = [];
    if (is_dir(plugin_path())) {
        $handle = opendir(plugin_path());
        if ($handle) {
            while (($path = readdir($handle)) !== false) {
                if ($path != '.' && $path != '..') {
                    $infoPath   = plugin_path() . $path . '/info.php';
                    $pluginInfo = is_file($infoPath) ? include($infoPath) : [];
                    if (! empty($pluginInfo)) {
                        if ($pluginInfo['status'] == $status || $status == 2) {
                            $routesPath = plugin_path() . $path . '/route.php';
                            $routes     = is_file($routesPath) ? include($routesPath) : [];
                            $pluginInfo['personalSide'] = [];
                            $pluginInfo['catalog']      = [];
                            $pluginInfo['single']       = [];
                            $pluginInfo['link']         = [];
                            $pluginInfo['page']         = [];
                            foreach ($routes as $key => $route) {
                                $route['plugin'] = $pluginInfo['name'];
                                switch ($route['type']) {
                                    case 'page':
                                        array_push($pluginInfo['page'], $route);
                                        break;
                                    case 'catalog':
                                        array_push($pluginInfo['catalog'], $route);
                                        array_push($pluginInfo['link'], $route);
                                        break;
                                    case 'single':
                                        array_push($pluginInfo['single'], $route);
                                        array_push($pluginInfo['link'], $route);
                                        break;
                                }
                                if (isset($route['personalSide']) && $route['personalSide'] === 1) {
                                    array_push($pluginInfo['personalSide'], $route);
                                }
                            }
                            array_push($list, $pluginInfo);
                        }
                    }
                }
            }
        }
    }
    return $list;
}

/**
 * 插件路由
 */
function plugin_route(string $name): array
{
    $data = [];
    foreach (plugin_list() as $key => $val) {
        foreach ($val[$name] as $k => $link) {
            array_push($data, $link);
        }
    }
    return $data;
}

/**
 * 插件位置
 */
function plugin_path(): string 
{
    return str_replace('\\', '/', public_path() . 'plugins/');
}

/**
 * 插件是否存在
 */
function plugin_exist(string $name): bool
{
    $list = plugin_list(2);
    $bool = array_search($name, array_column($list, 'name')) === false ? false : true;
    return $bool;
}

/**
 * 主题名称
 */
function theme_name(): string
{
    $template  = request()->isMobile() ? 'mp_template' : 'pc_template';
    $themeName = config("app.$template");
    return $themeName;
}

/**
 * 主题位置
 */
function theme_path(): string
{
    return str_replace('\\', '/', public_path() . 'themes/');
}

/**
 * 当前主题位置
 */
function theme_path_now(): string
{
    return theme_path() . theme_name() . '/';
}

/**
 * 语言配置
 */
function lang_config(): array
{
    $list = unserialize(config('app.language'));
    $arr['default'] = "cn";
    $arr['allow']   = [];
    foreach ($list as $key => $val) {
        if ($val['status'] === 1) {
            array_push($arr['allow'], $val);
        }
        if ($val['default'] === 1) {
            $arr['default'] = $val['name'];
        }
    }
    $arr['allow'] = array_sort($arr['allow'], 'sort', 'desc');
    return $arr;
}

/**
 * 二维数组根据某个字段排序
 * @param array  $array  要排序的数组
 * @param string $keys   要排序的键字段
 * @param string $sort   排序类型SORT_ASC/SORT_DESC 
 * @return array         排序后的数组
 */
function array_sort(array $array, string $keys, $sort = "desc"): array
{
    $order     = $sort === 'asc' ? SORT_ASC : SORT_DESC;
    $keysValue = [];
    foreach ($array as $k => $v) {
        $keysValue[$k] = $v[$keys];
    }
    array_multisort($keysValue, $order, $array);
    return $array;
}

/**
 * 生成不重复的字符串
 * @param  int     $len  需要的长度
 * @return string
 */
function rand_id(int $length): string 
{
    $arr = array_merge(range(0, 9), range('a', 'z'), range('A', 'Z'));
    $str = '';
    $arr_len = count($arr);
    for ($i = 0; $i < $length; $i++){
        $rand = mt_rand(0, $arr_len-1);
        $str.=$arr[$rand];
    }
    return $str;
}

/**
 * 替换内容的图片、视频、音频、PDF 路径
 * @param  string   $content 需要替换的内容、兼容线上线下访问资源
 * @return string
 */
function content_replace(string $content): string 
{
    if (! empty($content)) {
        $reg[] = "/(src)=(\\\?)([\"|']?)([^ \"'>]+\.(swf|flv|mp4|rmvb|avi|mpeg|ra|ram|mov|wmv)((\?[^ \"'>]+)?))\\2\\3/i";
        $reg[] = "/(src)=(\\\?)([\"|']?)([^ \"'>]+\.(mp3|wav|wma|ogg|ape|acc))\\2\\3/i";
        $reg[] = "/(src)=(\\\?)([\"|']?)([^ \"'>]+\.(gif|jpg|jpeg|bmp|png))\\2\\3/i";
        $reg[] = "/(src)=(\\\?)([\"|']?)([^ \"'>]+\.(pdf))\\2\\3/i";
        foreach ($reg as $key => $val) {
            $content = src_replace($content, $val);
        }
        return $content;
    } else {
        return  '';
    }
}
/**
 * 根据正则批量替换路径
 * @param  string $content  需要替换的内容
 * @param  string $reg      正则表达式
 * @return string         
 */
function src_replace(string $content, string $reg): string
{
    $url = request()->domain() . request()->root() . '/upload'; // 兼容本地
    preg_match_all($reg, $content, $match);
    if (! empty($match[0])) {
        foreach ($match[0] as $key => $img) {
            preg_match('/"(.*?)"/', $img, $src);
            if (! empty($src)) {
                $old = $src[1];
                $oldArr = explode('/upload', $old);
                if (count($oldArr) > 1) {
                    $new = $url . $oldArr[1];
                    str_replace($old, $new, $content);
                }
            }
        }
    }
    return $content;
}

/**
 * api发起POST请求
 * @param  string  $func     [请求api方法]
 * @param  string  $data     [请求api数据]
 */
function api_post(string $func, $data = [])
{
    $data['token'] = env('app_token');
    $url    = config('app.api').'/api/' . $func;
    $output = curl($url, $data);
    if (substr($output, 0, 2) === "a:") {
        $res = unserialize($output);
    } else {
        $res = json_decode($output, true);
    }
    return $res;
}
    
/**
 * CURL请求函数:支持POST及基本header头信息定义
 * @param  string  $api_url      [请求远程链接]
 * @param  array   $post_data    [请求远程数据]
 * @param  array   $header       [头信息数组]
 * @param  string  $referer_url  [来源url]
 */
function curl(string $api_url, $post_data = [], $header = [], $referer_url = '')
{
    /**初始化CURL句柄**/
    $ch = curl_init();
    curl_setopt( $ch, CURLOPT_URL, $api_url);
    /**配置返回信息**/
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);//获取的信息以文件流的形式返回，不直接输出
    curl_setopt( $ch, CURLOPT_HEADER, 0);//不返回header部分
    /**配置超时**/
    curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 10);//连接前等待时间,0不等待
    curl_setopt( $ch, CURLOPT_TIMEOUT, 60);//连接后等待时间,0不等待。如下载mp3
    /**配置页面重定向**/
    curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);//跟踪爬取重定向页面
    curl_setopt( $ch, CURLOPT_MAXREDIRS, 10);//指定最多的HTTP重定向的数量
    curl_setopt( $ch, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
    /**配置Header、请求头、协议信息**/
    $header[] = "CLIENT-IP:".request()->ip();
    $header[] = "X-FORWARDED-FOR:".request()->ip();
    curl_setopt( $ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt( $ch, CURLOPT_ENCODING, "");//Accept-Encoding编码，支持"identity"/"deflate"/"gzip",空支持所有编码
    curl_setopt( $ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; Baiduspider/2.0; +" . request()->domain(). request()->domain() . ")" );
    //模拟浏览器头信息
    $referer_url && curl_setopt( $ch, CURLOPT_REFERER, request()->domain());//伪造来源地址
    /**配置POST请求**/
    if($post_data && is_array($post_data)) {
        curl_setopt( $ch, CURLOPT_POST, 1 );//支持post提交数据
        curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
    }
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//禁止 cURL 验证对等证书
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);//是否检测服务器的域名与证书上的是否一致
    $data = curl_exec( $ch );
    if (curl_errno($ch)) {
        // 捕抓异常
        return ['status' => 'error', 'message' => curl_error($ch)];
    } else {
        // 正常返回
        curl_close($ch);    
        return $data;
    }
}